package ift604.projet;

import ift604.projet.feeling.CheckIn;
import ift604.projet.utils.GeoPosition;
import ift604.projet.utils.HTTPUtil;

import java.net.URL;
import java.util.ArrayList;

import org.apache.http.NameValuePair;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

import android.app.Service;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.Point;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;

public class UpdaterService extends Service {
	private static final String TAG = "UpdaterService";
	public static int DELAY = 60000; // delai entre les mises a jour, en milisecondes
	private boolean runFlag = false; 
	private Updater updater;
	private MapMyFeelingsApplication application;
	private MapView mapView; // vue de la carte routiere dans MapMyFeelingsActivity

	public ArrayList<CheckIn> checkIns = new ArrayList<CheckIn>();


	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();

		application = (MapMyFeelingsApplication)getApplication();
		application.updaterService = this;
		mapView = (MapView)application.mapMyFeelingsActivity.findViewById(R.id.mapview);

		updater = new Updater(); 

		Log.d(TAG, "onCreated");
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		super.onStartCommand(intent, flags, startId);

		if (!runFlag) {
			this.runFlag = true; 
			updater.start();
		}

		Log.d(TAG, "onStarted");
		return START_STICKY;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();

		this.runFlag = false; 
		this.updater.interrupt(); 
		this.updater = null;

		Log.d(TAG, "onDestroyed");
	}

	/**
	 * Thread s'occupant des mises a jour
	 */
	private class Updater extends Thread {
		public Updater() {
			super("Feelings-Updater");
		}

		@Override
		public void run() {
			while (runFlag) {
				try {
					updateMapCheckins();
					Thread.sleep(DELAY);
				} catch (InterruptedException e) {  
					runFlag = false;
				}
			}
		}
	}

	/**
	 * Fonction s'occupant d'aller recuperer les checkins a l'aide d'une requete HTTP GET
	 */
	public ArrayList<CheckIn> getCheckIns() {
		ArrayList<CheckIn> retour = new ArrayList<CheckIn>();

		String checkIns = HTTPUtil.sendGETRequest("http://ift604.alixg.com/api/feelings/format/json", new ArrayList<NameValuePair>());
		try {
			JSONArray json = (JSONArray) new JSONParser().parse(checkIns);
			for (Object element: json) {
				JSONObject jsonObject = (JSONObject)element;
				double latitude = Double.parseDouble((String)jsonObject.get("latitude"));
				double longitude = Double.parseDouble((String)jsonObject.get("longitude"));
				String emotion = (String)jsonObject.get("feeling_name");
				int id = Integer.parseInt((String)jsonObject.get("id"));
				String date = (String)jsonObject.get("date");

				retour.add(new CheckIn(id, latitude, longitude, emotion, date));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return retour;
	}

	class Marker extends com.google.android.maps.Overlay {
		GeoPoint location = null;
		CheckIn checkIn;
		public Marker(CheckIn checkIn) {
			super();
			this.checkIn = checkIn;
			location = GeoPosition.locationToGeoPoint(checkIn.getLatitude(), checkIn.getLongitude());
		}

		@Override
		public void draw(Canvas canvas, MapView mapView, boolean shadow) {
			super.draw(canvas, mapView, shadow);
			Point screenPoint = new Point();
			mapView.getProjection().toPixels(this.location, screenPoint);

			Paint pen = new Paint();
			pen.setColor(checkIn.getFeeling().getColor());
			pen.setStyle(Style.FILL_AND_STROKE);
			pen.setAlpha(40);
			canvas.drawCircle(screenPoint.x, screenPoint.y, 14, pen);

			pen.setColor(Color.BLACK);
			pen.setStyle(Style.STROKE);
			pen.setTextAlign(Align.CENTER);
			pen.setTextSize(16);
			pen.setTypeface(Typeface.create("Droid Sans", 1));

			canvas.drawText(checkIn.getFeeling().getName().substring(0, 1), screenPoint.x, screenPoint.y+5, pen);
		}    
	}


	
	private Handler mHandler = new Handler(Looper.getMainLooper()); 

	public synchronized void updateMapCheckins() {
		mHandler.post(new Runnable() { 
			public void run() { 
				new GetCheckInsTask().execute();
			}
		});
	}

	private class GetCheckInsTask extends AsyncTask<URL, Integer, ArrayList<CheckIn>> {    
		@Override
		protected ArrayList<CheckIn> doInBackground(URL... urls) {
			checkIns.clear();
			checkIns.addAll(getCheckIns());
			return checkIns;
		}     

		@Override
		protected void onPostExecute(ArrayList<CheckIn> result) {         
			mapView.getOverlays().clear();

			MyLocationOverlay myPos = application.mapMyFeelingsActivity.getMyPos();
			mapView.getOverlays().add(myPos);

			for (CheckIn checkIn: result) {
				mapView.getOverlays().add(new Marker(checkIn));    
			}
			mapView.invalidate();
		} 
	}

}
